package com.dao;

import com.model.Course;
import com.model.Curriculum;
import com.model.StuException;
import com.model.Student;
import com.util.XmlUtil;
import org.dom4j.Document;
import org.dom4j.Element;

import java.util.ArrayList;
import java.util.List;
import java.util.Vector;

/**
 * Created by guin_guo on 2015/10/31.
 */
public class CurriculumDao {
    public final static String CURRICULUM_XML = "curriculum.xml";
    private Document cd;
    private StudentDao sd;
    private static class Singleton{
        public static CurriculumDao instance = new CurriculumDao();
    }
    public static CurriculumDao getInstance(){
        return Singleton.instance;
    }
    private CurriculumDao() {
        cd = XmlUtil.getCurriDocument();
    }
    private void write(){
        XmlUtil.write2XML(cd,CURRICULUM_XML);
    }

    /**
     * 增加Curriculum接口
     * 每次添加前先判断当前老师（学生）是否有课表，有则删除
     * @param curriculum
     */
    public void add(Curriculum curriculum) {
        Curriculum c = null;
        if(curriculum.getTeacher()!=null){
            c = this.loadByTeacher(curriculum.getTeacher());
            if (c != null) {
                //delete
                this.delete(curriculum.getTeacher(),null);
            }
        }
        if (curriculum.getStudent() != null) {
            c = this.loadByStudent(curriculum.getStudent());
            if (c != null) {
                //delete
                this.delete(null,curriculum.getStudent());
            }
        }
        Element root    = cd.getRootElement();
        Element cs = root.addElement("curriculum");
        cs.addAttribute("id", String.valueOf(XmlUtil.getMaxId(cd, "/curriculums/curriculum") + 1));
        if (curriculum.getTeacher() != null) {
            cs.addElement("teacher").addText(curriculum.getTeacher());
        } else cs.addElement("teacher").addText("null");
        if (curriculum.getStudent()!= null) {
            cs.addElement("student").addText(curriculum.getStudent());
        } else cs.addElement("student").addText("null");
        cs.addElement("name").addText(curriculum.getName());
        Element ccs = cs.addElement("courses");
        for(int i=0;i<6;i++) {
            for (int j = 0; j < 7; j++) {
                if(curriculum.getCourses()[i][j]!=null){
                    Element cccs = ccs.addElement("course");
                    cccs.addElement("place").addText(curriculum.getCourses()[i][j].getPlace());
                    cccs.addElement("name").addText(curriculum.getCourses()[i][j].getName());
                    cccs.addElement("teacher").addText(curriculum.getCourses()[i][j].getTeachet()==null?"null":curriculum.getCourses()[i][j].getTeachet());
                    cccs.addElement("student").addText(curriculum.getCourses()[i][j].getStudent()==null?"null": curriculum.getCourses()[i][j].getStudent());
                    cccs.addElement("time").addText(getTime(i));
                    curriculum.getCourses()[i][j].setI(i);
                    curriculum.getCourses()[i][j].setJ(j);
                    cccs.addElement("i").addText(i+"");
                    cccs.addElement("j").addText(j+"");
                }
            }
        }
        write();
    }

    /**
     *  添加整个专业的课表，参数中Curriculum的student和teacher可以为null
     * @param curriculum
     */
    public void addStuCurr(Curriculum curriculum) {
        sd =  StudentDao.getInstance();
        List<Student> students = sd.listByMajor(curriculum.getName());
        students.stream().forEach(student -> {
            curriculum.setStudent(student.getAccount());
            this.add(curriculum);
        });
    }
    /**
     * 根据老师或者学生学号删除课表
     * @param teacher
     * @param student
     */
    private void delete(String teacher, String student) {
        String path = "/curriculums/curriculum[";
        if (teacher != null) {
            path += "teacher='"+teacher+"']";
        }else if (student != null) {
            path += "student='"+student+"']";
        }
        Element curr = (Element) cd.selectSingleNode(path);
        if (curr != null) {
            cd.getRootElement().remove(curr);
        }else return;
    }

    /**
     * 获取对应时间
     * @param i
     * @return
     */
    private String getTime(int i) {
        switch (i) {
            case 0: return "1~2";
            case 1: return "3~4";
            case 2: return "5~6";
            case 3: return "7~8";
            case 4: return "9~10";
            case 5: return "11~13";
            default:return "null";
        }
    }

    /** TODO 重构
     * 获取所有的Course
     * @return List里面存放 Vector
     */
    public List<Vector> list() {
        String path = "/curriculums/curriculum";
        List<Element> els = cd.selectNodes(path);
        List<Vector> list = new ArrayList<>(els.size());
        for (Element e : els) {
            Vector v = new Vector();
            v.add(e.attributeValue("id"));
            v.add(e.elementText("student"));
            v.add(e.elementText("teacher"));
            v.add(e.elementText("name"));
            list.add(v);
        }
        return list;
    }

    /**
     * 根据老师查找课表
     * @param teacher
     * @return
     */
    public Curriculum loadByTeacher(String teacher) {
        if (teacher == null) {
            return null;
        }
        return loadByCondition("teacher", teacher);
    }
    /**
     * 根据学生学号查找课表
     * @param student
     * @return
     */
    public Curriculum loadByStudent(String student) {
        if (student == null) {
            return null;
        }
        return loadByCondition("student", student);
    }

    /**
     * 根据课表名称（专业）查询课表
     * @param name
     * @return
     */
    public Curriculum loadByName(String name) {
        return this.loadByCondition("name", name);
    }

    /**
     * 根据条件，参数查询课表，主要用于内部调用
     * @param condition
     * @param param
     * @return
     */
    public Curriculum loadByCondition(String condition ,String param) {
        String path = "/curriculums/curriculum["+condition+"='"+param+"']";
        Curriculum ccm = new Curriculum();
        Element curriculum = (Element)cd.selectSingleNode(path);
        if (curriculum == null) {
            return null;
        }
        ccm.setId(Integer.parseInt(curriculum.attributeValue("id")));
        ccm.setName(curriculum.elementText("name"));
        ccm.setTeacher(curriculum.elementText("teacher"));
        ccm.setStudent(curriculum.elementText("student"));
        Course[][] courses = new Course[6][7];
        List<Element> cs = curriculum.selectNodes("courses/course");
        for (Element e : cs) {
            Course c = new Course();
            c.setName(e.elementText("name"));
            c.setTime(e.elementText("time"));
            c.setStudent(e.elementText("student"));
            c.setTeachet(e.elementText("teacher"));
            c.setPlace(e.elementText("place"));
            int i = c.setI(Integer.parseInt(e.elementText("i")));
            int j = c.setJ(Integer.parseInt(e.elementText("j")));
            courses[i][j] = c;
        }
        ccm.setCourses(courses);
        return ccm;
    }
}
